<?php
declare(strict_types=1);
/**
 * 库存扣减服务
 */
namespace Service\CommodityService;
use Service\BaseService;
use Service\Code\Normal;
use App\Amqp\Producer\StockRedisServiceMessageProducer;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Amqp\Producer;
class StockRedisService extends BaseService
{
    const stock_cache_prefix = 'stock:goods:';
    const stock_cache_lock_wait_key = 'stock:goods:lockwait:';
    /**
     * 扣减库存服务
     * @param string $key
     * @param int $number
     */
    public function decrease(string $key,int $number)
    {
        try 
        {
            $redis = redis();
            
            //判断是否有库存调整如果有库存调整
            $is_lock = $redis->get(self::stock_cache_lock_wait_key.$key); 
            if( !empty($is_lock) ) {
                return Normal::returnCode(Normal::FAIL,"库存调整中，请稍后再试!");
            }
            
            $total_stock_number = $redis->get(self::stock_cache_prefix.$key);
            if( $total_stock_number <=0 ) {
                return Normal::returnCode(Normal::FAIL,"库存不足，请稍后再试!");
            }
            
            //开启事务
            $redis->multi();
            $redis->decr(self::stock_cache_prefix.$key,$number);
            $result = $redis->exec();
            $current_element = current($result);
            if( $current_element < 0 ) {
                return Normal::returnCode(Normal::FAIL,"扣减失败-{$current_element}");
            }
            
            //库存满足条件的情况下，投递消息到MQ
            try
            {
                $data = [
                    'goods_id'  => (string)$key,
                    'goods_num' => (string)$number
                ];
                $message = new StockRedisServiceMessageProducer($data);
                $producer = ApplicationContext::getContainer()->get(Producer::class);
                $result = $producer->produce($message,true);
                if( !$result ) {
                    return Normal::returnCode(Normal::FAIL,"扣减失败，消息投递失败");
                }
                return Normal::returnCode(Normal::SUC,"扣减成功，消息投递成功");
            } catch ( \Throwable $th) {
                return Normal::returnCode(Normal::FAIL,"扣减失败，消息投递失败-{$th->getMessage()},{$th->getFile()},{$th->getLine()}");
            }
        } 
        catch ( \Throwable $th )
        {
            return Normal::returnCode(Normal::FAIL,"扣减失败-{$th->getMessage()},{$th->getFile()},{$th->getLine()}");
        }
    }
    
    /**
     * 新增库存服务
     * @param string $key
     * @param int $number
     */
    public function increase(string $key,int $number)
    {
        try
        {
            $redis = redis();
            $redis->multi();
            $redis->incr($key,$number);
            $result = $redis->exec();
            $current_element = current($result);
            return Normal::returnCode(Normal::SUC,"新增成功-{$current_element}");
        }
        catch ( \Throwable $th )
        {
            return Normal::returnCode(Normal::FAIL,"新增失败-{$th->getMessage()},{$th->getFile()},{$th->getLine()}");
        }
    }
}